//
// Created by Yandel on 2024/11/29.
//
#include <stdbool.h>
#include "stdio.h"

typedef int Element;
#define MaxSize 6

typedef struct queue {
    Element data[MaxSize];//定义一个队列数组
    int front, rear; //front队头 、 rear队尾指针
} SQueue;

/**
 * 初始化队列
 * @param sQueue
 */
void InitQueue(SQueue *sQueue) {
    sQueue->front=sQueue->rear=0;
}
/**
 * 判断队列是否为空
 * @param sQueue
 * @return
 */
bool QueueEmpty(SQueue *sQueue)
{
    return sQueue->front==sQueue->rear;
}

/**
 * 入队 这种写法此方法牺牲一个存储单元来判断队满  ，当插入到倒数第二个时，后面插入不进，(sQueue->rear + 1) % MaxSize == sQueue->front 满足了
 * @param sQueue
 * @param element
 * @return
 */
bool OfferQueue(SQueue *sQueue, Element element) {
    //判断是否队满         队列下标是从0开始的
    if ((sQueue->rear + 1) % MaxSize == sQueue->front) return false; //入队时，front不动，rear后移，队满求余为0，等于front
    //插入元素
    sQueue->data[sQueue->rear] = element;
    //插完元素后队尾指针后移1位
    sQueue->rear = (sQueue->rear + 1) % MaxSize; //一个数求模于比它大的数等于该数本身  8%10 =8 ... 队首同理！
    return true;
}

/**
 * 出队
 * @param sQueue
 * @return
 */
Element PollQueue(SQueue *sQueue) {
    //出队元素
    Element element = sQueue->data[sQueue->front];
    //队首指针后移
    sQueue->front = (sQueue->front + 1) % MaxSize;
    return element;
}

/**
 * 总结：这种写法是先插值再队尾自增，也是要牺牲一个单元来判断是否队满
 * @return
 */
int main()
{
    SQueue sQueue;

    InitQueue(&sQueue);
    //入队
    OfferQueue(&sQueue,2);
    OfferQueue(&sQueue,3);
    OfferQueue(&sQueue,4);
    OfferQueue(&sQueue,5);
    OfferQueue(&sQueue,6);
    OfferQueue(&sQueue,7);// (sQueue->rear + 1) % MaxSize == sQueue->front 此方法牺牲一个存储单元来判断队满


    //出队
    for (int i = 0; i < 6; i++) {
        printf("%d", PollQueue(&sQueue));
        printf("\n");
    }



    return 0;
}










